/*
 * DIMACSCollectionParser.cpp
 *
 * Copyright 2012 Fabian Wenzelmann
 *
 * This file is part of Recognition-Procedures-for-Boolean-Functions.
 *
 * Recognition-Procedures-for-Boolean-Functions is free software: you
 * can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * Recognition-Procedures-for-Boolean-Functions is distributed in the hope
 * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 * Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Recognition-Procedures-for-Boolean-Functions.
 *
 * If not, see <http://www.gnu.org/licenses/>.
 */

#include "bfr/DIMACSCollectionParser.hpp"

#include <iostream>
#include <string>
#include <list>

#include "bfr/DIMACSParser.hpp"
#include "bfr/ClauseSet.hpp"

using std::string;
using std::pair;
using std::make_pair;
using std::istream;

namespace bfr {

DIMACSCollectionIterator::DIMACSCollectionIterator(size_t s,
                                    std::istream *st,
                                    DIMACSParser *pa,
                                    size_t p)
    : size(s), stream(st), pos(p), parser(pa) { }

DIMACSCollectionIterator::DIMACSCollectionIterator
        (const DIMACSCollectionIterator &other)
    : size(other.size), stream(other.stream), pos(other.pos),
      parser(other.parser) { }

DIMACSCollectionIterator&
DIMACSCollectionIterator::operator=(const DIMACSCollectionIterator &other) {
    if (this != &other) {
        size = other.size;
        stream = other.stream;
        pos = other.pos;
    }
    return *this;
}

DIMACSCollectionIterator& DIMACSCollectionIterator::operator++() {
    ++pos;
    return *this;
}

DIMACSCollectionIterator DIMACSCollectionIterator::operator++(int) {
    DIMACSCollectionIterator tmp(*this);
    operator++();
    return tmp;
}

bool DIMACSCollectionIterator::operator==(const DIMACSCollectionIterator& rhs) {
    return (pos == rhs.pos) && (stream == rhs.stream) && (size == rhs.size);
}

bool DIMACSCollectionIterator::operator!=(const DIMACSCollectionIterator& rhs) {
    return !((*this) == rhs);
}

bool DIMACSCollectionIterator::operator<(const DIMACSCollectionIterator& rhs) {
    return pos < rhs.pos;
}

std::pair<ClauseSet*, size_t> DIMACSCollectionIterator::operator*() {
    if (!(pos < size)) {
        throw string("You've already parsed all DNFs from the input.");
    }
    ClauseSet *cs = parser->parse(*stream);
    return make_pair(cs, parser->getVariableCount());
}

DIMACSCollectionParser::DIMACSCollectionParser(std::istream *in,
        size_t ns)
    : stream(in), numSets(ns), dp(new DIMACSParser()) { }

DIMACSCollectionParser::~DIMACSCollectionParser() {
    delete dp;
}

DIMACSCollectionParser::const_iterator DIMACSCollectionParser::begin() const {
    return DIMACSCollectionIterator(numSets, stream, dp);
}

DIMACSCollectionParser::const_iterator DIMACSCollectionParser::end() const {
    return DIMACSCollectionIterator(numSets, stream, dp, numSets);
}

}
